package com.spic.business.train.questions.service.impl;

import com.spic.business.common.datascope.anotation.BusinessDataScope;
import com.spic.business.train.questions.domain.TrainQuestionVo;
import com.spic.business.train.questions.domain.TrainQuestions;
import com.spic.business.train.questions.domain.TrainQuestionsOptions;
import com.spic.business.train.questions.mapper.TrainQuestionsMapper;
import com.spic.business.train.questions.service.ITrainQuestionsService;
import com.spic.common.core.exception.ServiceException;
import com.spic.common.core.utils.DateUtils;
import com.spic.common.core.utils.IdUtils;
import com.spic.common.core.utils.SecurityUtils;
import com.spic.common.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import static java.util.stream.Collectors.toList;


/**
 * 题库管理Service业务层处理
 *
 * @author renxiang
 * @date 2021-10-20
 */
@Service
public class TrainQuestionsServiceImpl implements ITrainQuestionsService
{
    @Autowired
    private TrainQuestionsMapper trainQuestionsMapper;

    /**
     * 查询题库管理
     *
     * @param id 题库管理主键
     * @return 题库管理
     */
    @Override
    public TrainQuestions selectTrainQuestionsById(String id)
    {
        return trainQuestionsMapper.selectTrainQuestionsById(id);
    }

    /**
     * 查询题库管理列表
     *
     * @param trainQuestions 题库管理
     * @return 题库管理
     */
    @Override
    @BusinessDataScope(menuPath = "business/train/questions/index")
    public List<TrainQuestions> selectTrainQuestionsList(TrainQuestions trainQuestions)
    {
        return trainQuestionsMapper.selectTrainQuestionsList(trainQuestions);
    }

    /**
     * 新增题库管理
     *
     * @param trainQuestions 题库管理
     * @return 结果
     */
    @Transactional
    @Override
    public int insertTrainQuestions(TrainQuestions trainQuestions)
    {
        trainQuestions.setId(IdUtils.fastUUID());
        trainQuestions.setCreateTime(DateUtils.getNowDate());
        int rows = trainQuestionsMapper.insertTrainQuestions(trainQuestions);
        insertTrainQuestionsOptions(trainQuestions);
        return rows;
    }

    /**
     * 修改题库管理
     *
     * @param trainQuestions 题库管理
     * @return 结果
     */
    @Transactional
    @Override
    public int updateTrainQuestions(TrainQuestions trainQuestions)
    {
        trainQuestions.setUpdateTime(DateUtils.getNowDate());
        trainQuestionsMapper.deleteTrainQuestionsOptionsByQuestionId(trainQuestions.getId());
        insertTrainQuestionsOptions(trainQuestions);
        return trainQuestionsMapper.updateTrainQuestions(trainQuestions);
    }

    /**
     * 批量删除题库管理
     *
     * @param ids 需要删除的题库管理主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteTrainQuestionsByIds(String[] ids)
    {
        trainQuestionsMapper.deleteTrainQuestionsOptionsByIds(ids);
        return trainQuestionsMapper.deleteTrainQuestionsByIds(ids);
    }

    /**
     * 删除题库管理信息
     *
     * @param id 题库管理主键
     * @return 结果
     */
    @Override
    public int deleteTrainQuestionsById(String id)
    {
        trainQuestionsMapper.deleteTrainQuestionsOptionsByQuestionId(id);
        return trainQuestionsMapper.deleteTrainQuestionsById(id);
    }

    /**
     * 新增试题答案项  判断题选项共用，题库ID为000 A 为 对，B为错信息
     *
     * @param trainQuestions 题库管理对象
     */
    public void insertTrainQuestionsOptions(TrainQuestions trainQuestions)
    {
        List<TrainQuestionsOptions> trainQuestionsOptionsList = trainQuestions.getTrainQuestionsOptionsList();
        String id = trainQuestions.getId();
        if (StringUtils.isNotNull(trainQuestionsOptionsList))
        {
            List<TrainQuestionsOptions> list = new ArrayList<TrainQuestionsOptions>();
            for (TrainQuestionsOptions trainQuestionsOptions : trainQuestionsOptionsList)
            {
                trainQuestionsOptions.setQuestionId(id);
                trainQuestionsOptions.setId(null);
                list.add(trainQuestionsOptions);
            }
            if (list.size() > 0)
            {
                trainQuestionsMapper.batchTrainQuestionsOptions(list);
            }
        }
    }
    /**
     * 验证答案正确以及得分比例
     * @param id 题库管理主键  answer 作答答案
     * @return 题库改题得分比例
     */
    @Override
    public Double selectTrainQuestionsScoreProportion(String id,String answertrim)
    {
        String answer = answertrim;
        TrainQuestions tq = trainQuestionsMapper.selectTrainQuestionsByIdAll(id);
        String answerSingleL = tq.getAnswerSingle().trim();
        String questionsType = tq.getQuestionsType();
        // 单选和判断
        if ("1".equals(questionsType) || "3".equals(questionsType)) {
            return answer.equals(answerSingleL)? 1.0d : 0.0d;
            // 多选题
        }else if("2".equals(questionsType)){
            return getScoreOfMultipleChoice(answer, answerSingleL.replaceAll("[^a-zA-Z0-9]",""));
            // 填空题
        }else if("4".equals(questionsType)){
            return getScoreOfCompletion(answer, tq);
        }
        return 0.0d;
    }

    @Override
    public String importData(List<TrainQuestionVo> trainQuestionVos, TrainQuestions trainQuestions)
    {
        String questionsType = trainQuestions.getQuestionsType();
        String courseType = trainQuestions.getCourseType();
        String questionsDifficulty = trainQuestions.getQuestionsDifficulty();


        if (StringUtils.isNull(trainQuestionVos) || trainQuestionVos.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        if(!trainQuestions.getQuestionsType().equals("4")){

            for (TrainQuestionVo trainQuestionVo : trainQuestionVos)
            {
                String changA = trainQuestionVo.getChangA();
                String changB = trainQuestionVo.getChangB();
                String changC = trainQuestionVo.getChangC();
                String changD = trainQuestionVo.getChangD();
                String changE = trainQuestionVo.getChangE();
                String id = IdUtils.fastUUID();
                TrainQuestions tr = new TrainQuestions();
                 tr.setQuestionsContent(trainQuestionVo.getQuestionsContent());
                 tr.setCourseType(courseType);
                 tr.setQuestionsDifficulty(questionsDifficulty);
                 tr.setQuestionsType(questionsType);
                 tr.setAnswerSingle(trainQuestionVo.getAnswer());
                 tr.setCreateBy(SecurityUtils.getUserId()+"");
                 tr.setDeptId(Long.valueOf(SecurityUtils.getDeptId()));
                 tr.setId(id);
                 tr.setCreateTime(DateUtils.getNowDate());
                 trainQuestionsMapper.insertTrainQuestions(tr);

                List<TrainQuestionsOptions> questionsList = new ArrayList<>();
                if(StringUtils.isNotEmpty(changA)){
                   TrainQuestionsOptions tro = new TrainQuestionsOptions();
                   tro.setQuestionId(id);
                   tro.setOptionsKey("A");
                   tro.setOptionsValue(changA.replaceAll("A、",""));
                    questionsList.add(tro);
                }
                if(StringUtils.isNotEmpty(changB)){
                    TrainQuestionsOptions tro = new TrainQuestionsOptions();
                    tro.setQuestionId(id);
                    tro.setOptionsKey("B");
                    tro.setOptionsValue(changB.replaceAll("B、",""));
                    questionsList.add(tro);
                }
                if(StringUtils.isNotEmpty(changC)){
                    TrainQuestionsOptions tro = new TrainQuestionsOptions();
                    tro.setQuestionId(id);
                    tro.setOptionsKey("C");
                    tro.setOptionsValue(changC.replaceAll("C、",""));
                    questionsList.add(tro);
                }
                if(StringUtils.isNotEmpty(changD)){
                    TrainQuestionsOptions tro = new TrainQuestionsOptions();
                    tro.setQuestionId(id);
                    tro.setOptionsKey("D");
                    tro.setOptionsValue(changD.replaceAll("D、",""));
                    questionsList.add(tro);
                }
                if(StringUtils.isNotEmpty(changE)){
                    TrainQuestionsOptions tro = new TrainQuestionsOptions();
                    tro.setQuestionId(id);
                    tro.setOptionsKey("E");
                    tro.setOptionsValue(changE.replaceAll("E、",""));
                    questionsList.add(tro);
                }

                trainQuestionsMapper.batchTrainQuestionsOptions(questionsList)       ;
            }

        } else{

        }
        return "success";
    }

    /***
     * 关于多选判分逻辑  错选 0 少选 一半分  全对 满分 答案支持 选项 ABC 也支持 id 用,号分割
     * @param answer
     * @param answerSingleL
     * @return
     */
    private Double getScoreOfMultipleChoice(String answer, String answerSingleL) {
        List<String> answerList = new ArrayList<>();
        List<String> answerSingleList = new ArrayList<>();
        if (Pattern.matches("[A-Z]{1,8}",answer)){
            char[] answerArr = answer.toCharArray();
            for (char a : answerArr) {
                answerList.add(a+"");
            }
            char[] answerSingleArr = answerSingleL.toCharArray();
            for (char a : answerSingleArr) {
                answerSingleList.add(a+"");
            }
        }else {
            answerList = Arrays.asList(answer.split(","));
            answerSingleList = Arrays.asList(answerSingleL.split(","));
        }
        List answerSingles = new ArrayList(answerSingleList);
        int answerListSize = answerList.size();
        int answerSinglesSize = answerSingles.size();
        // 选项多了 直接错
        if (answerListSize > answerSinglesSize){
            return 0.0d;
        }
        // 交集
        List<String> intersection = (List<String>) answerList.stream().filter(item -> answerSingles.contains(item)).collect(toList());
        // 全对
        if (answerListSize == answerSinglesSize && intersection.size() == answerSinglesSize){
           return 1.0d;
        }
        // 少选了 给一半分
        if(answerListSize < answerSinglesSize && intersection.size() == answerListSize){
           return 0.5d;
        }
        return 0.0d;
    }

    /***
     * 关于填空题判分逻辑 多个空 平均分配分数  也支持自定义分数比例
     * @param answer
     * @param tq
     * @return score
     */
    private Double getScoreOfCompletion(String answer, TrainQuestions tq) {
        Double scores = 0.0d;
        List<String> answerList = new ArrayList<>();
        if(answer.indexOf(",")!=-1){
            answerList = Arrays.asList(answer.split(","));
        }else {
            answerList.add(answer);
        }
        List<TrainQuestionsOptions> correctAnswerList = tq.getTrainQuestionsOptionsList();
        if (null == correctAnswerList || correctAnswerList.isEmpty()){
            return null;
        }
        for (int i = 0; i < answerList.size(); i++) {
            List<String>list = Arrays.asList(correctAnswerList.get(i).getOptionsValue().split(","));
            if (StringUtils.isNotNull(answerList.get(i)) && list.contains(answerList.get(i))){
                Double score =  correctAnswerList.get(i).getScoreProportion();
                // 当前选项没有设置估计得分比例时选择 每个选项平分 分数
                scores += (null == score) ? 1.0d/correctAnswerList.size() : score;
            }
        }
        return scores;
    }

}
